home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 November / PCWNOV07.iso / Software / Freeware / NSIS 2.29 / nsis-2.29-setup.exe / Include / LogicLib.nsh < prev    next >
Encoding:
Text File  |  2007-04-27  |  28.7 KB  |  776 lines

  1. ; NSIS LOGIC LIBRARY - LogicLib.nsh
  2. ; Version 2.5 - 23/08/2004
  3. ; By dselkirk@hotmail.com
  4. ; and eccles@users.sf.net
  5. ;
  6. ; Questions/Comments -
  7. ; See http://forums.winamp.com/showthread.php?s=&postid=1116241
  8. ;
  9. ; Description:
  10. ;   Provides the use of various logic statements within NSIS.
  11. ;
  12. ; Usage:
  13. ;   The following "statements" are available:
  14. ;       If|Unless..{ElseIf|ElseUnless}..[Else]..EndIf|EndUnless
  15. ;         - Conditionally executes a block of statements, depending on the value
  16. ;           of an expression.
  17. ;       AndIf|AndUnless|OrIf|OrUnless
  18. ;         - Adds any number of extra conditions to If, Unless, ElseIf and
  19. ;           ElseUnless statements.
  20. ;       IfThen..|..|
  21. ;         - Conditionally executes an inline statement, depending on the value
  22. ;           of an expression.
  23. ;       IfCmd..||..|
  24. ;         - Conditionally executes an inline statement, depending on a true
  25. ;           value of the provided NSIS function.
  26. ;       Select..{Case[2|3|4|5]}..[CaseElse|Default]..EndSelect
  27. ;         - Executes one of several blocks of statements, depending on the value
  28. ;           of an expression.
  29. ;       Switch..{Case|CaseElse|Default}..EndSwitch
  30. ;         - Jumps to one of several labels, depending on the value of an
  31. ;           expression.
  32. ;       Do[While|Until]..{ExitDo|Continue|Break}..Loop[While|Until]
  33. ;         - Repeats a block of statements until stopped, or depending on the
  34. ;           value of an expression.
  35. ;       While..{ExitWhile|Continue|Break}..EndWhile
  36. ;         - An alias for DoWhile..Loop (for backwards-compatibility)
  37. ;       For[Each]..{ExitFor|Continue|Break}..Next
  38. ;         - Repeats a block of statements varying the value of a variable.
  39. ;
  40. ;   The following "expressions" are available:
  41. ;       Standard (built-in) string tests (which are case-insensitive):
  42. ;         a == b; a != b
  43. ;       Additional case-insensitive string tests (using System.dll):
  44. ;         a S< b; a S>= b; a S> b; a S<= b
  45. ;       Case-sensitive string tests:
  46. ;         a S== b; a S!= b
  47. ;       Standard (built-in) signed integer tests:
  48. ;         a = b; a <> b; a < b; a >= b; a > b; a <= b
  49. ;       Standard (built-in) unsigned integer tests:
  50. ;         a U< b; a U>= b; a U> b; a U<= b
  51. ;       64-bit integer tests (using System.dll):
  52. ;         a L= b; a L<> b; a L< b; a L>= b; a L> b; a L<= b
  53. ;       Built-in NSIS flag tests:
  54. ;         ${Abort}; ${Errors}; ${RebootFlag}; ${Silent}
  55. ;       Built-in NSIS other tests:
  56. ;         ${FileExists} a
  57. ;       Any conditional NSIS instruction test:
  58. ;         ${Cmd} a
  59. ;       Section flag tests:
  60. ;         ${SectionIsSelected} a; ${SectionIsSectionGroup} a;
  61. ;         ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a;
  62. ;         ${SectionIsReadOnly} a; ${SectionIsExpanded} a;
  63. ;         ${SectionIsPartiallySelected} a
  64. ;
  65. ; Examples:
  66. ;   See LogicLib.nsi in the Examples folder for lots of example usage.
  67.  
  68. !verbose push
  69. !verbose 3
  70. !ifndef LOGICLIB_VERBOSITY
  71.   !define LOGICLIB_VERBOSITY 3
  72. !endif
  73. !define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY}
  74. !undef LOGICLIB_VERBOSITY
  75. !verbose ${_LOGICLIB_VERBOSITY}
  76.  
  77. !ifndef LOGICLIB
  78.   !define LOGICLIB
  79.   !define | "'"
  80.   !define || "' '"
  81.   !define LOGICLIB_COUNTER 0
  82.  
  83.   !include Sections.nsh
  84.  
  85.   !macro _LOGICLIB_TEMP
  86.     !ifndef _LOGICLIB_TEMP
  87.       !define _LOGICLIB_TEMP
  88.       Var /GLOBAL _LOGICLIB_TEMP  ; Temporary variable to aid the more elaborate logic tests
  89.     !endif
  90.   !macroend
  91.  
  92.   !macro _IncreaseCounter
  93.     !define _LOGICLIB_COUNTER ${LOGICLIB_COUNTER}
  94.     !undef LOGICLIB_COUNTER
  95.     !define /math LOGICLIB_COUNTER ${_LOGICLIB_COUNTER} + 1
  96.     !undef _LOGICLIB_COUNTER
  97.   !macroend
  98.  
  99.   !macro _PushLogic
  100.     !insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER}
  101.     !insertmacro _IncreaseCounter
  102.   !macroend
  103.  
  104.   !macro _PopLogic
  105.     !insertmacro _PopScope Logic
  106.   !macroend
  107.  
  108.   !macro _PushScope Type label
  109.     !ifdef _${Type}                                       ; If we already have a statement
  110.       !define _Cur${Type} ${_${Type}}
  111.       !undef _${Type}
  112.       !define _${Type} ${label}
  113.       !define ${_${Type}}Prev${Type} ${_Cur${Type}}       ; Save the current logic
  114.       !undef _Cur${Type}
  115.     !else
  116.       !define _${Type} ${label}                           ; Initialise for first statement
  117.     !endif
  118.   !macroend
  119.  
  120.   !macro _PopScope Type
  121.     !ifndef _${Type}
  122.       !error "Cannot use _Pop${Type} without a preceding _Push${Type}"
  123.     !endif
  124.     !ifdef ${_${Type}}Prev${Type}                         ; If a previous statment was active then restore it
  125.       !define _Cur${Type} ${_${Type}}
  126.       !undef _${Type}
  127.       !define _${Type} ${${_Cur${Type}}Prev${Type}}
  128.       !undef ${_Cur${Type}}Prev${Type}
  129.       !undef _Cur${Type}
  130.     !else
  131.       !undef _${Type}
  132.     !endif
  133.   !macroend
  134.  
  135.   ; String tests
  136.   !macro _== _a _b _t _f
  137.     StrCmp `${_a}` `${_b}` `${_t}` `${_f}`
  138.   !macroend
  139.  
  140.   !macro _!= _a _b _t _f
  141.     !insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}`
  142.   !macroend
  143.  
  144.   ; Case-sensitive string tests
  145.   !macro _S== _a _b _t _f
  146.     StrCmpS `${_a}` `${_b}` `${_t}` `${_f}`
  147.   !macroend
  148.  
  149.   !macro _S!= _a _b _t _f
  150.     !insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}`
  151.   !macroend
  152.  
  153.   ; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case)
  154.   !macro _StrCmpI _a _b _e _l _m
  155.     !insertmacro _LOGICLIB_TEMP
  156.     System::Call `kernel32::lstrcmpiA(ts, ts) i.s` `${_a}` `${_b}`
  157.     Pop $_LOGICLIB_TEMP
  158.     IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}`
  159.   !macroend
  160.  
  161.   !macro _S< _a _b _t _f
  162.     !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
  163.   !macroend
  164.  
  165.   !macro _S>= _a _b _t _f
  166.     !insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}`
  167.   !macroend
  168.  
  169.   !macro _S> _a _b _t _f
  170.     !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
  171.   !macroend
  172.  
  173.   !macro _S<= _a _b _t _f
  174.     !insertmacro _S> `${_a}` `${_b}` `${_f}` `${_t}`
  175.   !macroend
  176.  
  177.   ; Integer tests
  178.   !macro _= _a _b _t _f
  179.     IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}`
  180.   !macroend
  181.  
  182.   !macro _<> _a _b _t _f
  183.     !insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}`
  184.   !macroend
  185.  
  186.   !macro _< _a _b _t _f
  187.     IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
  188.   !macroend
  189.  
  190.   !macro _>= _a _b _t _f
  191.     !insertmacro _< `${_a}` `${_b}` `${_f}` `${_t}`
  192.   !macroend
  193.  
  194.   !macro _> _a _b _t _f
  195.     IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
  196.   !macroend
  197.  
  198.   !macro _<= _a _b _t _f
  199.     !insertmacro _> `${_a}` `${_b}` `${_f}` `${_t}`
  200.   !macroend
  201.  
  202.   ; Unsigned integer tests (NB: no need for extra equality tests)
  203.   !macro _U< _a _b _t _f
  204.     IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
  205.   !macroend
  206.  
  207.   !macro _U>= _a _b _t _f
  208.     !insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}`
  209.   !macroend
  210.  
  211.   !macro _U> _a _b _t _f
  212.     IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
  213.   !macroend
  214.  
  215.   !macro _U<= _a _b _t _f
  216.     !insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}`
  217.   !macroend
  218.  
  219.   ; Int64 tests
  220.   !macro _Int64Cmp _a _o _b _t _f
  221.     !insertmacro _LOGICLIB_TEMP
  222.     System::Int64Op `${_a}` `${_o}` `${_b}`
  223.     Pop $_LOGICLIB_TEMP
  224.     !insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}`
  225.   !macroend
  226.  
  227.   !macro _L= _a _b _t _f
  228.     !insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}`
  229.   !macroend
  230.  
  231.   !macro _L<> _a _b _t _f
  232.     !insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}`
  233.   !macroend
  234.  
  235.   !macro _L< _a _b _t _f
  236.     !insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}`
  237.   !macroend
  238.  
  239.   !macro _L>= _a _b _t _f
  240.     !insertmacro _L< `${_a}` `${_b}` `${_f}` `${_t}`
  241.   !macroend
  242.  
  243.   !macro _L> _a _b _t _f
  244.     !insertmacro _Int64Cmp `${_a}` > `${_b}` `${_t}` `${_f}`
  245.   !macroend
  246.  
  247.   !macro _L<= _a _b _t _f
  248.     !insertmacro _L> `${_a}` `${_b}` `${_f}` `${_t}`
  249.   !macroend
  250.  
  251.   ; Flag tests
  252.   !macro _Abort _a _b _t _f
  253.     IfAbort `${_t}` `${_f}`
  254.   !macroend
  255.   !define Abort `"" Abort ""`
  256.  
  257.   !macro _Errors _a _b _t _f
  258.     IfErrors `${_t}` `${_f}`
  259.   !macroend
  260.   !define Errors `"" Errors ""`
  261.  
  262.   !macro _FileExists _a _b _t _f
  263.     IfFileExists `${_b}` `${_t}` `${_f}`
  264.   !macroend
  265.   !define FileExists `"" FileExists`
  266.  
  267.   !macro _RebootFlag _a _b _t _f
  268.     IfRebootFlag `${_t}` `${_f}`
  269.   !macroend
  270.   !define RebootFlag `"" RebootFlag ""`
  271.  
  272.   !macro _Silent _a _b _t _f
  273.     IfSilent `${_t}` `${_f}`
  274.   !macroend
  275.   !define Silent `"" Silent ""`
  276.  
  277.   ; "Any instruction" test
  278.   !macro _Cmd _a _b _t _f
  279.     !define _t=${_t}
  280.     !ifdef _t=                                            ; If no true label then make one
  281.       !define __t _LogicLib_Label_${LOGICLIB_COUNTER}
  282.       !insertmacro _IncreaseCounter
  283.     !else
  284.       !define __t ${_t}
  285.     !endif
  286.     ${_b} ${__t}
  287.     !define _f=${_f}
  288.     !ifndef _f=                                           ; If a false label then go there
  289.       Goto ${_f}
  290.     !endif
  291.     !undef _f=${_f}
  292.     !ifdef _t=                                            ; If we made our own true label then place it
  293.       ${__t}:
  294.     !endif
  295.     !undef __t
  296.     !undef _t=${_t}
  297.   !macroend
  298.   !define Cmd `"" Cmd`
  299.  
  300.   ; Section flag test
  301.   !macro _SectionFlagIsSet _a _b _t _f
  302.     !insertmacro _LOGICLIB_TEMP
  303.     SectionGetFlags `${_b}` $_LOGICLIB_TEMP
  304.     IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}`
  305.     !insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}`
  306.   !macroend
  307.   !define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet`
  308.   !define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet`
  309.   !define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet`
  310.   !define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet`
  311.   !define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet`
  312.   !define SectionIsBold `${SF_BOLD} SectionFlagIsSet`
  313.   !define SectionIsReadOnly `${SF_RO} SectionFlagIsSet`
  314.   !define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet`
  315.   !define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet`
  316.  
  317.   !define IfCmd `!insertmacro _IfThen "" Cmd ${|}`
  318.  
  319.   !macro _If _c _a _o _b
  320.     !verbose push
  321.     !verbose ${LOGICLIB_VERBOSITY}
  322.     !insertmacro _PushLogic
  323.     !define ${_Logic}If
  324.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the Else
  325.     !insertmacro _IncreaseCounter
  326.     !define _c=${_c}
  327.     !ifdef _c=true                                        ; If is true
  328.       !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
  329.     !else                                                 ; If condition is false
  330.       !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
  331.     !endif
  332.     !undef _c=${_c}
  333.     !verbose pop
  334.   !macroend
  335.   !define If     `!insertmacro _If true`
  336.   !define Unless `!insertmacro _If false`
  337.  
  338.   !macro _And _c _a _o _b
  339.     !verbose push
  340.     !verbose ${LOGICLIB_VERBOSITY}
  341.     !ifndef _Logic | ${_Logic}If
  342.       !error "Cannot use And without a preceding If or Unless"
  343.     !endif
  344.     !ifndef ${_Logic}Else
  345.       !error "Cannot use And following an Else"
  346.     !endif
  347.     !define _c=${_c}
  348.     !ifdef _c=true                                        ; If is true
  349.       !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
  350.     !else                                                 ; If condition is false
  351.       !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
  352.     !endif
  353.     !undef _c=${_c}
  354.     !verbose pop
  355.   !macroend
  356.   !define AndIf     `!insertmacro _And true`
  357.   !define AndUnless `!insertmacro _And false`
  358.  
  359.   !macro _Or _c _a _o _b
  360.     !verbose push
  361.     !verbose ${LOGICLIB_VERBOSITY}
  362.     !ifndef _Logic | ${_Logic}If
  363.       !error "Cannot use Or without a preceding If or Unless"
  364.     !endif
  365.     !ifndef ${_Logic}Else
  366.       !error "Cannot use Or following an Else"
  367.     !endif
  368.     !define _label _LogicLib_Label_${LOGICLIB_COUNTER}                           ; Skip this test as we already
  369.     !insertmacro _IncreaseCounter
  370.     Goto ${_label}                                        ; have a successful result
  371.     ${${_Logic}Else}:                                     ; Place the Else label
  372.     !undef ${_Logic}Else                                  ; and remove it
  373.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new If
  374.     !insertmacro _IncreaseCounter
  375.     !define _c=${_c}
  376.     !ifdef _c=true                                        ; If is true
  377.       !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
  378.     !else                                                 ; If condition is false
  379.       !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
  380.     !endif
  381.     !undef _c=${_c}
  382.     ${_label}:
  383.     !undef _label
  384.     !verbose pop
  385.   !macroend
  386.   !define OrIf     `!insertmacro _Or true`
  387.   !define OrUnless `!insertmacro _Or false`
  388.  
  389.   !macro _Else
  390.     !verbose push
  391.     !verbose ${LOGICLIB_VERBOSITY}
  392.     !ifndef _Logic | ${_Logic}If
  393.       !error "Cannot use Else without a preceding If or Unless"
  394.     !endif
  395.     !ifndef ${_Logic}Else
  396.       !error "Cannot use Else following an Else"
  397.     !endif
  398.     !ifndef ${_Logic}EndIf                                ; First Else for this If?
  399.       !define ${_Logic}EndIf _LogicLib_Label_${LOGICLIB_COUNTER}                 ; Get a label for the EndIf
  400.       !insertmacro _IncreaseCounter
  401.     !endif
  402.     Goto ${${_Logic}EndIf}                                ; Go to the EndIf
  403.     ${${_Logic}Else}:                                     ; Place the Else label
  404.     !undef ${_Logic}Else                                  ; and remove it
  405.     !verbose pop
  406.   !macroend
  407.   !define Else `!insertmacro _Else`
  408.  
  409.   !macro _ElseIf _c _a _o _b
  410.     !verbose push
  411.     !verbose ${LOGICLIB_VERBOSITY}
  412.     ${Else}                                               ; Perform the Else
  413.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new If
  414.     !insertmacro _IncreaseCounter
  415.     !define _c=${_c}
  416.     !ifdef _c=true                                        ; If is true
  417.       !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
  418.     !else                                                 ; If condition is false
  419.       !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
  420.     !endif
  421.     !undef _c=${_c}
  422.     !verbose pop
  423.   !macroend
  424.   !define ElseIf     `!insertmacro _ElseIf true`
  425.   !define ElseUnless `!insertmacro _ElseIf false`
  426.  
  427.   !macro _EndIf _n
  428.     !verbose push
  429.     !verbose ${LOGICLIB_VERBOSITY}
  430.     !ifndef _Logic | ${_Logic}If
  431.       !error "Cannot use End${_n} without a preceding If or Unless"
  432.     !endif
  433.     !ifdef ${_Logic}Else
  434.       ${${_Logic}Else}:                                   ; Place the Else label
  435.       !undef ${_Logic}Else                                ; and remove it
  436.     !endif
  437.     !ifdef ${_Logic}EndIf
  438.       ${${_Logic}EndIf}:                                  ; Place the EndIf
  439.       !undef ${_Logic}EndIf                               ; and remove it
  440.     !endif
  441.     !undef ${_Logic}If
  442.     !insertmacro _PopLogic
  443.     !verbose pop
  444.   !macroend
  445.   !define EndIf     `!insertmacro _EndIf If`
  446.   !define EndUnless `!insertmacro _EndIf Unless`
  447.  
  448.   !macro _IfThen _a _o _b _t
  449.     !verbose push
  450.     !verbose ${LOGICLIB_VERBOSITY}
  451.     ${If} `${_a}` `${_o}` `${_b}`
  452.       ${_t}
  453.     ${EndIf}
  454.     !verbose pop
  455.   !macroend
  456.   !define IfThen `!insertmacro _IfThen`
  457.  
  458.   !macro _ForEach _v _f _t _o _s
  459.     !verbose push
  460.     !verbose ${LOGICLIB_VERBOSITY}
  461.     StrCpy "${_v}" "${_f}"                                ; Assign the initial value
  462.     Goto +2                                               ; Skip the loop expression for the first iteration
  463.     !define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression
  464.     !define _o=${_o}
  465.     !ifdef _o=+                                           ; Check the loop expression operator
  466.       !define __o >                                       ; to determine the correct loop condition
  467.     !else ifdef _o=-
  468.       !define __o <
  469.     !else
  470.       !error "Unsupported ForEach step operator (must be + or -)"
  471.     !endif
  472.     !undef _o=${_o}
  473.     !insertmacro _Do For false `${_v}` `${__o}` `${_t}`   ; Let Do do the rest
  474.     !undef __o
  475.     !verbose pop
  476.   !macroend
  477.   !define ForEach `!insertmacro _ForEach`
  478.  
  479.   !macro _For _v _f _t
  480.     !verbose push
  481.     !verbose ${LOGICLIB_VERBOSITY}
  482.     ${ForEach} `${_v}` `${_f}` `${_t}` + 1                ; Pass on to ForEach
  483.     !verbose pop
  484.   !macroend
  485.   !define For `!insertmacro _For`
  486.  
  487.   !define ExitFor `!insertmacro _Goto ExitFor For`
  488.  
  489.   !define Next      `!insertmacro _Loop For Next "" "" "" ""`
  490.  
  491.   !define While     `!insertmacro _Do While true`
  492.  
  493.   !define ExitWhile `!insertmacro _Goto ExitWhile While`
  494.  
  495.   !define EndWhile  `!insertmacro _Loop While EndWhile "" "" "" ""`
  496.  
  497.   !macro _Do _n _c _a _o _b
  498.     !verbose push
  499.     !verbose ${LOGICLIB_VERBOSITY}
  500.     !insertmacro _PushLogic
  501.     !define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER}                   ; Get a label for the start of the loop
  502.     !insertmacro _IncreaseCounter
  503.     ${${_Logic}${_n}}:
  504.     !insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER}        ; Get a label for the end of the loop
  505.     !insertmacro _IncreaseCounter
  506.     !insertmacro _PushScope Break ${_Exit${_n}}           ; Break goes to the end of the loop
  507.     !ifdef _DoLoopExpression
  508.       ${_DoLoopExpression}                                ; Special extra parameter for inserting code
  509.       !undef _DoLoopExpression                            ; between the Continue label and the loop condition
  510.     !endif
  511.     !define _c=${_c}
  512.     !ifdef _c=                                            ; No starting condition
  513.       !insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER}       ; Get a label for Continue at the end of the loop
  514.       !insertmacro _IncreaseCounter
  515.     !else
  516.       !insertmacro _PushScope Continue ${${_Logic}${_n}}  ; Continue goes to the start of the loop
  517.       !ifdef _c=true                                      ; If is true
  518.         !insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}}
  519.       !else                                               ; If condition is false
  520.         !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ""
  521.       !endif
  522.     !endif
  523.     !undef _c=${_c}
  524.     !define ${_Logic}Condition ${_c}                      ; Remember the condition used
  525.     !verbose pop
  526.   !macroend
  527.   !define Do      `!insertmacro _Do Do "" "" "" ""`
  528.   !define DoWhile `!insertmacro _Do Do true`
  529.   !define DoUntil `!insertmacro _Do Do false`
  530.  
  531.   !macro _Goto _n _s
  532.     !verbose push
  533.     !verbose ${LOGICLIB_VERBOSITY}
  534.     !ifndef _${_n}
  535.       !error "Cannot use ${_n} without a preceding ${_s}"
  536.     !endif
  537.     Goto ${_${_n}}
  538.     !verbose pop
  539.   !macroend
  540.   !define ExitDo   `!insertmacro _Goto ExitDo Do`
  541.  
  542.   !macro _Loop _n _e _c _a _o _b
  543.     !verbose push
  544.     !verbose ${LOGICLIB_VERBOSITY}
  545.     !ifndef _Logic | ${_Logic}${_n}
  546.       !error "Cannot use ${_e} without a preceding ${_n}"
  547.     !endif
  548.     !define _c=${${_Logic}Condition}
  549.     !ifdef _c=                                            ; If Do had no condition place the Continue label
  550.       ${_Continue}:
  551.     !endif
  552.     !undef _c=${${_Logic}Condition}
  553.     !define _c=${_c}
  554.     !ifdef _c=                                            ; No ending condition
  555.       Goto ${${_Logic}${_n}}
  556.     !else ifdef _c=true                                   ; If condition is true
  557.       !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}}
  558.     !else                                                 ; If condition is false
  559.       !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}}
  560.     !endif
  561.     !undef _c=${_c}
  562.     Goto ${_Continue}                                     ; Just to ensure it is referenced at least once
  563.     ${_Exit${_n}}:                                        ; Place the loop exit point
  564.     !undef ${_Logic}Condition
  565.     !insertmacro _PopScope Continue
  566.     !insertmacro _PopScope Break
  567.     !insertmacro _PopScope Exit${_n}
  568.     !undef ${_Logic}${_n}
  569.     !insertmacro _PopLogic
  570.     !verbose pop
  571.   !macroend
  572.   !define Loop      `!insertmacro _Loop Do Loop "" "" "" ""`
  573.   !define LoopWhile `!insertmacro _Loop Do LoopWhile true`
  574.   !define LoopUntil `!insertmacro _Loop Do LoopUntil false`
  575.  
  576.   !define Continue `!insertmacro _Goto Continue "For or Do or While"`
  577.   !define Break    `!insertmacro _Goto Break "For or Do or While"`
  578.  
  579.   !macro _Select _a
  580.     !verbose push
  581.     !verbose ${LOGICLIB_VERBOSITY}
  582.     !insertmacro _PushLogic
  583.     !define ${_Logic}Select `${_a}`                       ; Remember the left hand side of the comparison
  584.     !verbose pop
  585.   !macroend
  586.   !define Select `!insertmacro _Select`
  587.  
  588.   !macro _Select_CaseElse
  589.     !verbose push
  590.     !verbose ${LOGICLIB_VERBOSITY}
  591.     !ifndef _Logic | ${_Logic}Select
  592.       !error "Cannot use Case without a preceding Select"
  593.     !endif
  594.     !ifdef ${_Logic}EndSelect                             ; This is set only after the first case
  595.       !ifndef ${_Logic}Else
  596.         !error "Cannot use Case following a CaseElse"
  597.       !endif
  598.       Goto ${${_Logic}EndSelect}                          ; Go to the EndSelect
  599.       ${${_Logic}Else}:                                   ; Place the Else label
  600.       !undef ${_Logic}Else                                ; and remove it
  601.     !else
  602.       !define ${_Logic}EndSelect _LogicLib_Label_${LOGICLIB_COUNTER}             ; Get a label for the EndSelect
  603.       !insertmacro _IncreaseCounter
  604.     !endif
  605.     !verbose pop
  606.   !macroend
  607.   !define CaseElse `!insertmacro _CaseElse`
  608.   !define Case_Else `!insertmacro _CaseElse`              ; Compatibility with 2.2 and earlier
  609.   !define Default `!insertmacro _CaseElse`                ; For the C-minded
  610.  
  611.   !macro _Select_Case _a
  612.     !verbose push
  613.     !verbose ${LOGICLIB_VERBOSITY}
  614.     ${CaseElse}                                           ; Perform the CaseElse
  615.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
  616.     !insertmacro _IncreaseCounter
  617.     !insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else}
  618.     !verbose pop
  619.   !macroend
  620.   !define Case `!insertmacro _Case`
  621.  
  622.   !macro _Case2 _a _b
  623.     !verbose push
  624.     !verbose ${LOGICLIB_VERBOSITY}
  625.     ${CaseElse}                                           ; Perform the CaseElse
  626.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
  627.     !insertmacro _IncreaseCounter
  628.     !insertmacro _== `${${_Logic}Select}` `${_a}` +2 ""
  629.     !insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else}
  630.     !verbose pop
  631.   !macroend
  632.   !define Case2 `!insertmacro _Case2`
  633.  
  634.   !macro _Case3 _a _b _c
  635.     !verbose push
  636.     !verbose ${LOGICLIB_VERBOSITY}
  637.     ${CaseElse}                                           ; Perform the CaseElse
  638.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
  639.     !insertmacro _IncreaseCounter
  640.     !insertmacro _== `${${_Logic}Select}` `${_a}` +3 ""
  641.     !insertmacro _== `${${_Logic}Select}` `${_b}` +2 ""
  642.     !insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else}
  643.     !verbose pop
  644.   !macroend
  645.   !define Case3 `!insertmacro _Case3`
  646.  
  647.   !macro _Case4 _a _b _c _d
  648.     !verbose push
  649.     !verbose ${LOGICLIB_VERBOSITY}
  650.     ${CaseElse}                                           ; Perform the CaseElse
  651.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
  652.     !insertmacro _IncreaseCounter
  653.     !insertmacro _== `${${_Logic}Select}` `${_a}` +4 ""
  654.     !insertmacro _== `${${_Logic}Select}` `${_b}` +3 ""
  655.     !insertmacro _== `${${_Logic}Select}` `${_c}` +2 ""
  656.     !insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else}
  657.     !verbose pop
  658.   !macroend
  659.   !define Case4 `!insertmacro _Case4`
  660.  
  661.   !macro _Case5 _a _b _c _d _e
  662.     !verbose push
  663.     !verbose ${LOGICLIB_VERBOSITY}
  664.     ${CaseElse}                                           ; Perform the CaseElse
  665.     !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
  666.     !insertmacro _IncreaseCounter
  667.     !insertmacro _== `${${_Logic}Select}` `${_a}` +5 ""
  668.     !insertmacro _== `${${_Logic}Select}` `${_b}` +4 ""
  669.     !insertmacro _== `${${_Logic}Select}` `${_c}` +3 ""
  670.     !insertmacro _== `${${_Logic}Select}` `${_d}` +2 ""
  671.     !insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else}
  672.     !verbose pop
  673.   !macroend
  674.   !define Case5 `!insertmacro _Case5`
  675.  
  676.   !macro _EndSelect
  677.     !verbose push
  678.     !verbose ${LOGICLIB_VERBOSITY}
  679.     !ifndef _Logic | ${_Logic}Select
  680.       !error "Cannot use EndSelect without a preceding Select"
  681.     !endif
  682.     !ifdef ${_Logic}Else
  683.       ${${_Logic}Else}:                                   ; Place the Else label
  684.       !undef ${_Logic}Else                                ; and remove it
  685.     !endif
  686.     !ifdef ${_Logic}EndSelect                             ; This won't be set if there weren't any cases
  687.       ${${_Logic}EndSelect}:                              ; Place the EndSelect
  688.       !undef ${_Logic}EndSelect                           ; and remove it
  689.     !endif
  690.     !undef ${_Logic}Select
  691.     !insertmacro _PopLogic
  692.     !verbose pop
  693.   !macroend
  694.   !define EndSelect `!insertmacro _EndSelect`
  695.  
  696.   !macro _Switch _a
  697.     !verbose push
  698.     !verbose ${LOGICLIB_VERBOSITY}
  699.     !insertmacro _PushLogic
  700.     !insertmacro _PushScope Switch ${_Logic}              ; Keep a separate stack for switch data
  701.     !insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER}            ; Get a lable for beyond the end of the switch
  702.     !insertmacro _IncreaseCounter
  703.     !define ${_Switch}Var `${_a}`                         ; Remember the left hand side of the comparison
  704.     !tempfile ${_Switch}Tmp                               ; Create a temporary file
  705.     !define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER}                  ; Get a label for the end of the switch
  706.     !insertmacro _IncreaseCounter
  707.     Goto ${${_Logic}Switch}                               ; and go there
  708.     !verbose pop
  709.   !macroend
  710.   !define Switch `!insertmacro _Switch`
  711.  
  712.   !macro _Case _a
  713.     !verbose push
  714.     !verbose ${LOGICLIB_VERBOSITY}
  715.     !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
  716.       !insertmacro _Select_Case `${_a}`
  717.     !else ifndef _Switch                                  ; If not then check for an active Switch
  718.       !error "Cannot use Case without a preceding Select or Switch"
  719.     !else
  720.       !define _label _LogicLib_Label_${LOGICLIB_COUNTER}                         ; Get a label for this case,
  721.       !insertmacro _IncreaseCounter
  722.       ${_label}:                                          ; place it and add it's check to the temp file
  723.       !appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n`
  724.       !undef _label
  725.     !endif
  726.     !verbose pop
  727.   !macroend
  728.  
  729.   !macro _CaseElse
  730.     !verbose push
  731.     !verbose ${LOGICLIB_VERBOSITY}
  732.     !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
  733.       !insertmacro _Select_CaseElse
  734.     !else ifndef _Switch                                  ; If not then check for an active Switch
  735.       !error "Cannot use Case without a preceding Select or Switch"
  736.     !else ifdef ${_Switch}Else                            ; Already had a default case?
  737.       !error "Cannot use CaseElse following a CaseElse"
  738.     !else
  739.       !define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER}                 ; Get a label for the default case,
  740.       !insertmacro _IncreaseCounter
  741.       ${${_Switch}Else}:                                  ; and place it
  742.     !endif
  743.     !verbose pop
  744.   !macroend
  745.  
  746.   !macro _EndSwitch
  747.     !verbose push
  748.     !verbose ${LOGICLIB_VERBOSITY}
  749.     !ifndef _Logic | ${_Logic}Switch
  750.       !error "Cannot use EndSwitch without a preceding Switch"
  751.     !endif
  752.     Goto ${_Break}                                        ; Skip the jump table
  753.     ${${_Logic}Switch}:                                   ; Place the end of the switch
  754.     !undef ${_Logic}Switch
  755.     !include "${${_Switch}Tmp}"                           ; Include the jump table
  756.     !delfile "${${_Switch}Tmp}"                           ; and clear it up
  757.     !ifdef ${_Switch}Else                                 ; Was there a default case?
  758.       Goto ${${_Switch}Else}                              ; then go there if all else fails
  759.       !undef ${_Switch}Else
  760.     !endif
  761.     !undef ${_Switch}Tmp
  762.     !undef ${_Switch}Var
  763.     ${_Break}:                                            ; Place the break label
  764.     !insertmacro _PopScope Break
  765.     !insertmacro _PopScope Switch
  766.     !insertmacro _PopLogic
  767.     !verbose pop
  768.   !macroend
  769.   !define EndSwitch `!insertmacro _EndSwitch`
  770.  
  771. !endif ; LOGICLIB
  772. !verbose 3
  773. !define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY}
  774. !undef _LOGICLIB_VERBOSITY
  775. !verbose pop
  776.